package com.sxyjhh.fg_data_push.service;

import com.sxyjhh.dbutil.basic.ConstConfig;
import com.sxyjhh.dbutil.basic.DBQueryUtils;
import com.sxyjhh.dbutil.utils.DBInfoUtil;
import com.sxyjhh.dbutil.utils.PageInfo;
import com.sxyjhh.fg_data_push.dao.FgDataPushRecodeRepository;
import com.sxyjhh.fg_data_push.po.FgDataPushRecode;
import com.sxyjhh.fg_data_push.utils.CommonUtils;
import com.sxyjhh.fg_data_push.utils.common.RegexpValidate;
import com.sxyjhh.fg_data_push.utils.util.XaUtil;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.sql.SQLException;
import java.util.*;

/**
 * 数据推送管理类
 */
@Service
public class PushDataManager {

    @Value("${output.datasource.ip}")
    private String dbIP;

    @Value("${output.datasource.db.name}")
    private String dbName;

    @Value("${output.datasource.username}")
    private String dbUserName;

    @Value("${output.datasource.password}")
    private String dbPassword;

    @Value("${output.datasource.port}")
    private String dbPort;

    @Value("${output.datasource.type}")
    private String type;

    @Value("${output.table.xybdb}")
    private String souTabName;

    @Value("${yth.push.data.path.pre}")
    private String pushUrl;

    @Autowired
    private DBQueryUtils dbQueryUtils;

    @Autowired
    private FgDataPushRecodeRepository fgDataPushRecodeRepository;

    private static Logger log = LoggerFactory.getLogger(PushDataManager.class);

    private String outTableName = "zjt_qy_xkxx";

    @Bean
    public DBQueryUtils getDbQueryUtils() {
        String url = "";
        ConstConfig.DBType dbType = ConstConfig.DBType.valueOf(Integer.valueOf(type));
        if ("3".equals(type)) {
            url = "jdbc:mysql://" + dbIP + ":" + dbPort + "/" + dbName + "?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useInformationSchema=true&useSSL=false";
        } else {
            url = DBInfoUtil.getDBUrl(dbType, dbIP, dbPort, dbName);
        }

        return new DBQueryUtils(DBInfoUtil.getDBDriverName(dbType),
                url, dbUserName, dbPassword, 5);
    }


    public boolean pushCreditData() throws Exception {

        Date sTime = new Date();
        int count = 0;
        List countList = dbQueryUtils.queryData("select count(1) as CUT from " + souTabName);
        if (!XaUtil.isEmpty(countList)) {
            JSONObject countJson = JSONObject.fromObject(countList.get(0));
            count = Integer.parseInt(countJson.get("CUT") + "");
        }

        if (count == 0) {
            return false;
        }

        System.out.println("ssssxxxxx");
        if (!"1".equals(pushDel(outTableName))) {
            return false;
        }
        System.out.println("ssssxxxxx");
        FgDataPushRecode fgDataPushRecode = new FgDataPushRecode();

        fgDataPushRecode.setDataType("yjl_xy");

        fgDataPushRecode.setNum(0);
        fgDataPushRecode.setTotalNum(0);

        fgDataPushRecodeRepository.save(fgDataPushRecode);

        int num = 1000;
        int batch = (count / num) + (count % num != 0 ? 1 : 0);

        StringBuilder sql = new StringBuilder();
        sql.append(" select * From ( select ROW_NUMBER()Over(order by id Desc) as tmpId,* from ");
        sql.append(souTabName);
        sql.append(") as tb where tmpId Between ");

        for (int i = 0; i < batch; i++) {
            String betweenSql = sql.toString() + ((i * 1000 + 1) + " and " + ((i + 1) * 1000));
            List dataList = dbQueryUtils.queryData(betweenSql);
            List<Map<String, Object>> list = conversionData(dataList);
            push(list, fgDataPushRecode.getId());
            System.out.println(dataList.size());
        }

        long endTime = new Date().getTime() - sTime.getTime();
        long finishedTime = endTime / 1000;
        log.info("==========" + outTableName + "==========");
        log.info("==========TASK END==========");
        log.info("==========TASK FINISHEDTIME==========");
        log.info(finishedTime + "S");
        FgDataPushRecode fgDataPush = fgDataPushRecodeRepository.findOne(fgDataPushRecode.getId());
        fgDataPush.setEndTime(new Date());
        fgDataPush.setFinishedTime(finishedTime);
        fgDataPushRecodeRepository.save(fgDataPush);
        return true;
    }

    private List<Map<String, Object>> conversionData(List data) {


        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < data.size(); i++) {
            Map<String, Object> map = (Map<String, Object>) data.get(i);
            map.remove("tmpId");
            Object XY010305 = map.get("XY010305");
            Object XY010306 = map.get("XY010306");
            Object XY010325 = map.get("XY010325");
            String XY010133 = map.get("XY010133") + "";//统一社会信用代码
            String XY010108 = map.get("XY010108") + "";//法定代表人（负责人）身份证件号码
            String XY010105 = map.get("XY010105") + "";//法定代表人（负责人）姓名
            String XY010302 = map.get("XY010302") + "";//
            String XY010301 = map.get("XY010301") + "";//
            String XY010303 = map.get("XY010303") + "";//
            String XY010307 = map.get("XY010307") + "";//许可机关

            String XY010107 = map.get("XY010107") + "";//法定代表人证件类型
            String XY010101 = map.get("XY010101") + "";//法定代表人证件类型

            String XY010501 = map.get("XY010501") + "";//

            if (XY010133.length() != 18 || RegexpValidate.length(XY010501)>10 ) {
                continue;
            }



            if (StringUtils.isBlank(XY010307) || "null".equalsIgnoreCase(XY010307)
                    ||StringUtils.isBlank(XY010101) || "null".equalsIgnoreCase(XY010101)) {
                continue;
            }

            if ("军官证".equals(XY010107) || "其他".equals(XY010107)
                    || StringUtils.isBlank(XY010107) || "null".equalsIgnoreCase(XY010107)) {
                continue;
            }

            if (XY010107.contains("身份证")) {
                if (XY010108.length() != 15 && XY010108.length() != 18) {
                    continue;
                }
                XY010107 = "身份证";
            } else if (XY010107.contains("护照")) {
                XY010107 = "护照号";
            }

            if (StringUtils.isBlank(XY010105) || "null".equalsIgnoreCase(XY010105)) {
                XY010105 = "空";
            }
            if (StringUtils.isBlank(XY010302) || "null".equalsIgnoreCase(XY010302)) {
                XY010302 = "无";
            }
            if (StringUtils.isBlank(XY010301) || "null".equalsIgnoreCase(XY010301)) {
                XY010301 = "无";
            }
            if (StringUtils.isBlank(XY010303) || "null".equalsIgnoreCase(XY010303)) {
                XY010303 = "无";
            }

            map.put("xy010305", XaUtil.isEmpty(XY010305) ? "" : CommonUtils.YYYYMMDDHHMMSS.format(XY010305));
            map.put("xy010306", XaUtil.isEmpty(XY010306) ? "" : CommonUtils.YYYYMMDDHHMMSS.format(XY010306));
            map.put("xy010325", XaUtil.isEmpty(XY010325) ? "" : CommonUtils.YYYYMMDDHHMMSS.format(XY010325));
            map.put("create_time", CommonUtils.YYYYMMDDHHMMSS.format(new Date()));
            map.put("update_time", map.get("create_time"));
            map.put("xy010105", XY010105);
            map.put("xy010302", XY010302);
            map.put("xy010301", XY010301);
            map.put("xy010303", XY010303);
            map.put("xy010133", ToDBC(XY010133));
            map.put("xy010501", ToDBC(XY010501));
            map.put("xy010107", XY010107);
            list.add(map);
        }
        return list;
    }

    private void push(List<Map<String, Object>> list, String recodeId) {

        RestTemplate restTemplate = new RestTemplate();
        FgDataPushRecode fgDataPushRecode = fgDataPushRecodeRepository.findOne(recodeId);
        long totalNum = fgDataPushRecode.getTotalNum();
        long num = fgDataPushRecode.getNum();
        fgDataPushRecode.setTotalNum(totalNum + list.size());

        MultiValueMap<String, Object> map = new LinkedMultiValueMap();

        String json = net.sf.json.JSONArray.fromObject(list).toString();
        log.info(json);
        System.out.println("ssssxxxxx");
        //System.out.println(json);
        map.add("ythType", "yjl_xy");
        map.add("dataArray", json);
        map.add("tableName", outTableName);
        String result = restTemplate.postForEntity(pushUrl + "creditPushData", map, String.class).getBody();
        if ("1".equals(result)) {
            log.info("DATAPUSH SUCCESS！");
            fgDataPushRecode.setNum(num + list.size());
        } else {
            log.info("PUSH DATA FAILURE!");
        }
        fgDataPushRecodeRepository.save(fgDataPushRecode);
    }

    private String pushDel(String tableName) {
        RestTemplate restTemplate = new RestTemplate();
        MultiValueMap<String, Object> map = new LinkedMultiValueMap();
        map.add("tableName", tableName);
        String result = restTemplate.postForEntity(pushUrl + "delData", map, String.class).getBody();
        return result;
    }

    public static String ToDBC(String input) {

        char c[] = input.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (c[i] == '\u3000') {
                c[i] = ' ';
            } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {
                c[i] = (char) (c[i] - 65248);

            }
        }
        String returnString = new String(c);

        return returnString;
    }
}
